Skip to content

Conversation

@alvin-r
Copy link
Contributor

@alvin-r alvin-r commented Apr 16, 2025

PR Type

  • Tests
  • Enhancement

Description

  • Remove Python version conditions in test print formatting.

  • Unify expected output for codeflash tests.

  • Update CI matrix to use simplified Python version identifiers.


Changes walkthrough 📝

Relevant files
Tests
test_instrument_tests.py
Simplify print expectations in test instrumentation           

tests/test_instrument_tests.py

  • Removed conditional print formatting based on Python versions.
  • Unified expected output string across tests.
  • Applied changes in three separate code sections.
  • +3/-12   
    Configuration changes
    unit-tests.yaml
    Update CI Python version matrix specification                       

    .github/workflows/unit-tests.yaml

  • Updated Python version matrix.
  • Simplified version numbers to base versions.
  • +1/-1     

    Need help?
  • Type /help how to ... in the comments thread for any questions about PR-Agent usage.
  • Check out the documentation for more information.
  • @github-actions github-actions bot added workflow-modified This PR modifies GitHub Actions workflows Review effort 2/5 labels Apr 16, 2025
    @github-actions
    Copy link

    PR Reviewer Guide 🔍

    Here are some key observations to aid the review process:

    ⏱️ Estimated effort to review: 2 🔵🔵⚪⚪⚪
    🧪 PR contains tests
    🔒 No security concerns identified
    ⚡ Recommended focus areas for review

    Expected Output Consistency

    The PR unifies the expected output print statements across Python versions by removing conditional logic. Please verify that the unified print format—and the slight indentation difference in one hunk—is intentional and does not affect the test outcomes in different environments.

        expected += """print(f"!######{{test_module_name}}:{{(test_class_name + '.' if test_class_name else '')}}{{test_name}}:{{function_name}}:{{loop_index}}:{{invocation_id}}######!")"""
        expected += """
        exception = None
        gc.disable()
        try:
            counter = time.perf_counter_ns()
            return_value = wrapped(*args, **kwargs)
            codeflash_duration = time.perf_counter_ns() - counter
        except Exception as e:
            codeflash_duration = time.perf_counter_ns() - counter
            exception = e
        gc.enable()
        pickled_return_value = pickle.dumps(exception) if exception else pickle.dumps(return_value)
        codeflash_cur.execute('INSERT INTO test_results VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)', (test_module_name, test_class_name, test_name, function_name, loop_index, invocation_id, codeflash_duration, pickled_return_value, 'function_call'))
        codeflash_con.commit()
        if exception:
            raise exception
        return return_value
    
    class TestPigLatin(unittest.TestCase):
    
        @timeout_decorator.timeout(15)
        def test_sort(self):
            codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
            codeflash_iteration = os.environ['CODEFLASH_TEST_ITERATION']
            codeflash_con = sqlite3.connect(f'{tmp_dir_path}_{{codeflash_iteration}}.sqlite')
            codeflash_cur = codeflash_con.cursor()
            codeflash_cur.execute('CREATE TABLE IF NOT EXISTS test_results (test_module_path TEXT, test_class_name TEXT, test_function_name TEXT, function_getting_tested TEXT, loop_index INTEGER, iteration_id TEXT, runtime INTEGER, return_value BLOB, verification_type TEXT)')
            input = [5, 4, 3, 2, 1, 0]
            output = codeflash_wrap(sorter, '{module_path}', 'TestPigLatin', 'test_sort', 'sorter', '1', codeflash_loop_index, codeflash_cur, codeflash_con, input)
            self.assertEqual(output, [0, 1, 2, 3, 4, 5])
            input = [5.0, 4.0, 3.0, 2.0, 1.0, 0.0]
            output = codeflash_wrap(sorter, '{module_path}', 'TestPigLatin', 'test_sort', 'sorter', '4', codeflash_loop_index, codeflash_cur, codeflash_con, input)
            self.assertEqual(output, [0.0, 1.0, 2.0, 3.0, 4.0, 5.0])
            input = list(reversed(range(5000)))
            self.assertEqual(codeflash_wrap(sorter, '{module_path}', 'TestPigLatin', 'test_sort', 'sorter', '7', codeflash_loop_index, codeflash_cur, codeflash_con, input), list(range(5000)))
            codeflash_con.close()
    """
        with tempfile.NamedTemporaryFile(mode="w") as f:
            f.write(code)
            f.flush()
            func = FunctionToOptimize(function_name="sorter", parents=[], file_path=Path(f.name))
            original_cwd = Path.cwd()
            run_cwd = Path(__file__).parent.parent.resolve()
            os.chdir(run_cwd)
            success, new_test = inject_profiling_into_existing_test(
                Path(f.name),
                [CodePosition(9, 17), CodePosition(13, 17), CodePosition(17, 17)],
                func,
                Path(f.name).parent,
                "unittest",
            )
            os.chdir(original_cwd)
        assert success
        assert new_test == expected.format(
            module_path=Path(f.name).name, tmp_dir_path=get_run_tmp_file(Path("test_return_values"))
        )
    
    
    def test_perfinjector_only_replay_test() -> None:
        code = """import dill as pickle
    import pytest
    from codeflash.tracing.replay_test import get_next_arg_and_return
    from codeflash.validation.equivalence import compare_results
    from packagename.ml.yolo.image_reshaping_utils import prepare_image_for_yolo as packagename_ml_yolo_image_reshaping_utils_prepare_image_for_yolo
    def test_prepare_image_for_yolo():
        for arg_val_pkl, return_val_pkl in get_next_arg_and_return('/home/saurabh/packagename/traces/first.trace', 3):
            args = pickle.loads(arg_val_pkl)
            return_val_1= pickle.loads(return_val_pkl)
            ret = packagename_ml_yolo_image_reshaping_utils_prepare_image_for_yolo(**args)
            assert compare_results(return_val_1, ret)
    """
        expected = """import gc
    import os
    import sqlite3
    import time
    
    import dill as pickle
    import pytest
    from packagename.ml.yolo.image_reshaping_utils import \\
        prepare_image_for_yolo as \\
        packagename_ml_yolo_image_reshaping_utils_prepare_image_for_yolo
    
    from codeflash.tracing.replay_test import get_next_arg_and_return
    from codeflash.validation.equivalence import compare_results
    
    
    def codeflash_wrap(wrapped, test_module_name, test_class_name, test_name, function_name, line_id, loop_index, codeflash_cur, codeflash_con, *args, **kwargs):
        test_id = f'{{test_module_name}}:{{test_class_name}}:{{test_name}}:{{line_id}}:{{loop_index}}'
        if not hasattr(codeflash_wrap, 'index'):
            codeflash_wrap.index = {{}}
        if test_id in codeflash_wrap.index:
            codeflash_wrap.index[test_id] += 1
        else:
            codeflash_wrap.index[test_id] = 0
        codeflash_test_index = codeflash_wrap.index[test_id]
        invocation_id = f'{{line_id}}_{{codeflash_test_index}}'
        """
        expected += """print(f"!######{{test_module_name}}:{{(test_class_name + '.' if test_class_name else '')}}{{test_name}}:{{function_name}}:{{loop_index}}:{{invocation_id}}######!")"""
        expected += """
        exception = None
        gc.disable()
        try:
            counter = time.perf_counter_ns()
            return_value = wrapped(*args, **kwargs)
            codeflash_duration = time.perf_counter_ns() - counter
        except Exception as e:
            codeflash_duration = time.perf_counter_ns() - counter
            exception = e
        gc.enable()
        pickled_return_value = pickle.dumps(exception) if exception else pickle.dumps(return_value)
        codeflash_cur.execute('INSERT INTO test_results VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)', (test_module_name, test_class_name, test_name, function_name, loop_index, invocation_id, codeflash_duration, pickled_return_value, 'function_call'))
        codeflash_con.commit()
        if exception:
            raise exception
        return return_value
    
    def test_prepare_image_for_yolo():
        codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
        codeflash_iteration = os.environ['CODEFLASH_TEST_ITERATION']
        codeflash_con = sqlite3.connect(f'{tmp_dir_path}_{{codeflash_iteration}}.sqlite')
        codeflash_cur = codeflash_con.cursor()
        codeflash_cur.execute('CREATE TABLE IF NOT EXISTS test_results (test_module_path TEXT, test_class_name TEXT, test_function_name TEXT, function_getting_tested TEXT, loop_index INTEGER, iteration_id TEXT, runtime INTEGER, return_value BLOB, verification_type TEXT)')
    """
        if sys.version_info < (3, 11):
            expected += """    for (arg_val_pkl, return_val_pkl) in get_next_arg_and_return('/home/saurabh/packagename/traces/first.trace', 3):
    """
        else:
            expected += """    for arg_val_pkl, return_val_pkl in get_next_arg_and_return('/home/saurabh/packagename/traces/first.trace', 3):
    """
        expected += """        args = pickle.loads(arg_val_pkl)
            return_val_1 = pickle.loads(return_val_pkl)
            ret = codeflash_wrap(packagename_ml_yolo_image_reshaping_utils_prepare_image_for_yolo, '{module_path}', None, 'test_prepare_image_for_yolo', 'packagename_ml_yolo_image_reshaping_utils_prepare_image_for_yolo', '0_2', codeflash_loop_index, codeflash_cur, codeflash_con, **args)
            assert compare_results(return_val_1, ret)
        codeflash_con.close()
    """
        with tempfile.NamedTemporaryFile(mode="w") as f:
            f.write(code)
            f.flush()
            func = FunctionToOptimize(function_name="prepare_image_for_yolo", parents=[], file_path=Path("module.py"))
            original_cwd = Path.cwd()
            run_cwd = Path(__file__).parent.parent.resolve()
            os.chdir(run_cwd)
            success, new_test = inject_profiling_into_existing_test(
                Path(f.name), [CodePosition(10, 14)], func, Path(f.name).parent, "pytest"
            )
            os.chdir(original_cwd)
        assert success
        assert new_test == expected.format(
            module_path=Path(f.name).name, tmp_dir_path=get_run_tmp_file(Path("test_return_values"))
        )
    
    
    def test_perfinjector_bubble_sort_results() -> None:
        computed_fn_opt = False
        code = """from code_to_optimize.bubble_sort import sorter
    
    
    def test_sort():
        input = [5, 4, 3, 2, 1, 0]
        output = sorter(input)
        assert output == [0, 1, 2, 3, 4, 5]
    
        input = [5.0, 4.0, 3.0, 2.0, 1.0, 0.0]
        output = sorter(input)
        assert output == [0.0, 1.0, 2.0, 3.0, 4.0, 5.0]"""
    
        expected = (
            """import gc
    import os
    import sqlite3
    import time
    
    import dill as pickle
    
    from code_to_optimize.bubble_sort import sorter
    
    
    """
            + codeflash_wrap_string
            + """
    def test_sort():
        codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
        codeflash_iteration = os.environ['CODEFLASH_TEST_ITERATION']
        codeflash_con = sqlite3.connect(f'{tmp_dir_path}_{{codeflash_iteration}}.sqlite')
        codeflash_cur = codeflash_con.cursor()
        codeflash_cur.execute('CREATE TABLE IF NOT EXISTS test_results (test_module_path TEXT, test_class_name TEXT, test_function_name TEXT, function_getting_tested TEXT, loop_index INTEGER, iteration_id TEXT, runtime INTEGER, return_value BLOB, verification_type TEXT)')
        input = [5, 4, 3, 2, 1, 0]
        output = codeflash_wrap(sorter, '{module_path}', None, 'test_sort', 'sorter', '1', codeflash_loop_index, codeflash_cur, codeflash_con, input)
        assert output == [0, 1, 2, 3, 4, 5]
        input = [5.0, 4.0, 3.0, 2.0, 1.0, 0.0]
        output = codeflash_wrap(sorter, '{module_path}', None, 'test_sort', 'sorter', '4', codeflash_loop_index, codeflash_cur, codeflash_con, input)
        assert output == [0.0, 1.0, 2.0, 3.0, 4.0, 5.0]
        codeflash_con.close()
    """
        )
    
        expected_perfonly = (
            """import gc
    import os
    import time
    
    from code_to_optimize.bubble_sort import sorter
    
    
    """
            + codeflash_wrap_perfonly_string
            + """
    def test_sort():
        codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
        input = [5, 4, 3, 2, 1, 0]
        output = codeflash_wrap(sorter, '{module_path}', None, 'test_sort', 'sorter', '1', codeflash_loop_index, input)
        assert output == [0, 1, 2, 3, 4, 5]
        input = [5.0, 4.0, 3.0, 2.0, 1.0, 0.0]
        output = codeflash_wrap(sorter, '{module_path}', None, 'test_sort', 'sorter', '4', codeflash_loop_index, input)
        assert output == [0.0, 1.0, 2.0, 3.0, 4.0, 5.0]
    """
        )
    
        test_path = (
            Path(__file__).parent.resolve()
            / "../code_to_optimize/tests/pytest/test_perfinjector_bubble_sort_results_temp.py"
        ).resolve()
        test_path_perf = (
            Path(__file__).parent.resolve()
            / "../code_to_optimize/tests/pytest/test_perfinjector_bubble_sort_results_perf_temp.py"
        ).resolve()
        try:
            with test_path.open("w") as f:
                f.write(code)
            code_path = (Path(__file__).parent.resolve() / "../code_to_optimize/bubble_sort.py").resolve()
            tests_root = Path(__file__).parent.resolve() / "../code_to_optimize/tests/pytest/"
            project_root_path = (Path(__file__).parent / "..").resolve()
            original_cwd = Path.cwd()
            run_cwd = Path(__file__).parent.parent.resolve()
            func = FunctionToOptimize(function_name="sorter", parents=[], file_path=code_path)
            os.chdir(run_cwd)
            success, new_test = inject_profiling_into_existing_test(
                test_path,
                [CodePosition(6, 13), CodePosition(10, 13)],
                func,
                project_root_path,
                "pytest",
                mode=TestingMode.BEHAVIOR,
            )
            os.chdir(original_cwd)
            assert success
            assert new_test is not None
            assert new_test.replace('"', "'") == expected.format(
                module_path="code_to_optimize.tests.pytest.test_perfinjector_bubble_sort_results_temp",
                tmp_dir_path=get_run_tmp_file(Path("test_return_values")),
            ).replace('"', "'")
    
            success, new_perf_test = inject_profiling_into_existing_test(
                test_path,
                [CodePosition(6, 13), CodePosition(10, 13)],
                func,
                project_root_path,
                "pytest",
                mode=TestingMode.PERFORMANCE,
            )
            assert success
            assert new_perf_test is not None
            assert new_perf_test.replace('"', "'") == expected_perfonly.format(
                module_path="code_to_optimize.tests.pytest.test_perfinjector_bubble_sort_results_temp",
                tmp_dir_path=get_run_tmp_file(Path("test_return_values")),
            ).replace('"', "'")
    
            with test_path.open("w") as f:
                f.write(new_test)
    
            # Overwrite old test with new instrumented test
    
            test_config = TestConfig(
                tests_root=tests_root,
                tests_project_rootdir=project_root_path,
                project_root_path=project_root_path,
                test_framework="pytest",
                pytest_cmd="pytest",
            )
            func_optimizer = FunctionOptimizer(function_to_optimize=func, test_cfg=test_config)
            test_env = os.environ.copy()
            test_env["CODEFLASH_TEST_ITERATION"] = "0"
            test_env["CODEFLASH_LOOP_INDEX"] = "1"
            test_type = TestType.EXISTING_UNIT_TEST
            test_files = TestFiles(
                test_files=[
                    TestFile(
                        instrumented_behavior_file_path=test_path,
                        test_type=test_type,
                        original_file_path=test_path,
                        benchmarking_file_path=test_path_perf,
                    )
                ]
            )
            test_results, coverage_data = func_optimizer.run_and_parse_tests(
                testing_type=TestingMode.BEHAVIOR,
                test_env=test_env,
                test_files=test_files,
                optimization_iteration=0,
                pytest_min_loops=1,
                pytest_max_loops=1,
                testing_time=0.1,
            )
            assert test_results[0].id.function_getting_tested == "sorter"
            assert test_results[0].id.iteration_id == "1_0"
            assert test_results[0].id.test_class_name is None
            assert test_results[0].id.test_function_name == "test_sort"
            assert (
                test_results[0].id.test_module_path
                == "code_to_optimize.tests.pytest.test_perfinjector_bubble_sort_results_temp"
            )
            assert test_results[0].runtime > 0
            assert test_results[0].did_pass
            assert test_results[0].return_value == ([0, 1, 2, 3, 4, 5],)
    
            assert test_results[1].id.function_getting_tested == "sorter"
            assert test_results[1].id.iteration_id == "4_0"
            assert test_results[1].id.test_class_name is None
            assert test_results[1].id.test_function_name == "test_sort"
            assert (
                test_results[1].id.test_module_path
                == "code_to_optimize.tests.pytest.test_perfinjector_bubble_sort_results_temp"
            )
            assert test_results[1].runtime > 0
            assert test_results[1].did_pass
    
            with test_path_perf.open("w") as f:
                f.write(new_perf_test)
    
            test_results_perf, _ = func_optimizer.run_and_parse_tests(
                testing_type=TestingMode.PERFORMANCE,
                test_env=test_env,
                test_files=test_files,
                optimization_iteration=0,
                pytest_min_loops=1,
                pytest_max_loops=1,
                testing_time=0.1,
            )
            assert test_results_perf[0].id.function_getting_tested == "sorter"
            assert test_results_perf[0].id.iteration_id == "1_0"
            assert test_results_perf[0].id.test_class_name is None
            assert test_results_perf[0].id.test_function_name == "test_sort"
            assert (
                test_results_perf[0].id.test_module_path
                == "code_to_optimize.tests.pytest.test_perfinjector_bubble_sort_results_temp"
            )
            assert test_results_perf[0].runtime > 0
            assert test_results_perf[0].did_pass
            assert test_results_perf[0].return_value is None
    
            assert test_results_perf[1].id.function_getting_tested == "sorter"
            assert test_results_perf[1].id.iteration_id == "4_0"
            assert test_results_perf[1].id.test_class_name is None
            assert test_results_perf[1].id.test_function_name == "test_sort"
            assert (
                test_results_perf[1].id.test_module_path
                == "code_to_optimize.tests.pytest.test_perfinjector_bubble_sort_results_temp"
            )
            assert test_results_perf[1].runtime > 0
            assert test_results_perf[1].did_pass
            out_str = """codeflash stdout: Sorting list
    result: [0, 1, 2, 3, 4, 5]
    
    codeflash stdout: Sorting list
    result: [0.0, 1.0, 2.0, 3.0, 4.0, 5.0]"""
            assert out_str == test_results_perf[1].stdout
            ctx_result = func_optimizer.get_code_optimization_context()
            code_context: CodeOptimizationContext = ctx_result.unwrap()
            original_helper_code: dict[Path, str] = {}
            helper_function_paths = {hf.file_path for hf in code_context.helper_functions}
            for helper_function_path in helper_function_paths:
                with helper_function_path.open(encoding="utf8") as f:
                    helper_code = f.read()
                    original_helper_code[helper_function_path] = helper_code
            computed_fn_opt = True
            line_profiler_output_file = add_decorator_imports(
                func_optimizer.function_to_optimize, code_context)
            line_profile_results, _ = func_optimizer.run_and_parse_tests(
                testing_type=TestingMode.LINE_PROFILE,
                test_env=test_env,
                test_files=test_files,
                optimization_iteration=0,
                pytest_min_loops=1,
                pytest_max_loops=1,
                testing_time=0.1,
                line_profiler_output_file = line_profiler_output_file
            )
            tmp_lpr = list(line_profile_results["timings"].keys())
            assert len(tmp_lpr) == 1 and line_profile_results["timings"][tmp_lpr[0]][0][1]==2
        finally:
            if computed_fn_opt:
                func_optimizer.write_code_and_helpers(
                    func_optimizer.function_to_optimize_source_code, original_helper_code, func_optimizer.function_to_optimize.file_path
                )
            test_path.unlink(missing_ok=True)
            test_path_perf.unlink(missing_ok=True)
    
    
    def test_perfinjector_bubble_sort_parametrized_results() -> None:
        computed_fn_opt = False
        code = """from code_to_optimize.bubble_sort import sorter
    import pytest
    
    
    @pytest.mark.parametrize(
        "input, expected_output",
        [
            ([5, 4, 3, 2, 1, 0], [0, 1, 2, 3, 4, 5]),
            ([5.0, 4.0, 3.0, 2.0, 1.0, 0.0], [0.0, 1.0, 2.0, 3.0, 4.0, 5.0]),
            (list(reversed(range(50))), list(range(50))),
        ],
    )
    def test_sort_parametrized(input, expected_output):
        output = sorter(input)
        assert output == expected_output
    """
        expected = (
            """import gc
    import os
    import sqlite3
    import time
    
    import dill as pickle
    import pytest
    
    from code_to_optimize.bubble_sort import sorter
    
    
    """
            + codeflash_wrap_string
            + """
    @pytest.mark.parametrize('input, expected_output', [([5, 4, 3, 2, 1, 0], [0, 1, 2, 3, 4, 5]), ([5.0, 4.0, 3.0, 2.0, 1.0, 0.0], [0.0, 1.0, 2.0, 3.0, 4.0, 5.0]), (list(reversed(range(50))), list(range(50)))])
    def test_sort_parametrized(input, expected_output):
        codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
        codeflash_iteration = os.environ['CODEFLASH_TEST_ITERATION']
        codeflash_con = sqlite3.connect(f'{tmp_dir_path}_{{codeflash_iteration}}.sqlite')
        codeflash_cur = codeflash_con.cursor()
        codeflash_cur.execute('CREATE TABLE IF NOT EXISTS test_results (test_module_path TEXT, test_class_name TEXT, test_function_name TEXT, function_getting_tested TEXT, loop_index INTEGER, iteration_id TEXT, runtime INTEGER, return_value BLOB, verification_type TEXT)')
        output = codeflash_wrap(sorter, '{module_path}', None, 'test_sort_parametrized', 'sorter', '0', codeflash_loop_index, codeflash_cur, codeflash_con, input)
        assert output == expected_output
        codeflash_con.close()
    """
        )
    
        expected_perfonly = (
            """import gc
    import os
    import time
    
    import pytest
    
    from code_to_optimize.bubble_sort import sorter
    
    
    """
            + codeflash_wrap_perfonly_string
            + """
    @pytest.mark.parametrize('input, expected_output', [([5, 4, 3, 2, 1, 0], [0, 1, 2, 3, 4, 5]), ([5.0, 4.0, 3.0, 2.0, 1.0, 0.0], [0.0, 1.0, 2.0, 3.0, 4.0, 5.0]), (list(reversed(range(50))), list(range(50)))])
    def test_sort_parametrized(input, expected_output):
        codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
        output = codeflash_wrap(sorter, '{module_path}', None, 'test_sort_parametrized', 'sorter', '0', codeflash_loop_index, input)
        assert output == expected_output
    """
        )
        code_path = (Path(__file__).parent.resolve() / "../code_to_optimize/bubble_sort.py").resolve()
        test_path = (
            Path(__file__).parent.resolve()
            / "../code_to_optimize/tests/pytest/test_perfinjector_bubble_sort_parametrized_results_temp.py"
        ).resolve()
        test_path_perf = (
            Path(__file__).parent.resolve()
            / "../code_to_optimize/tests/pytest/test_perfinjector_bubble_sort_parametrized_results_temp_perf.py"
        ).resolve()
        try:
            with open(test_path, "w") as f:
                f.write(code)
    
            tests_root = (Path(__file__).parent.resolve() / "../code_to_optimize/tests/pytest/").resolve()
            project_root_path = (Path(__file__).parent.resolve() / "../").resolve()
            original_cwd = Path.cwd()
            run_cwd = Path(__file__).parent.parent.resolve()
    
            func = FunctionToOptimize(function_name="sorter", parents=[], file_path=code_path)
            os.chdir(run_cwd)
            success, new_test = inject_profiling_into_existing_test(
                test_path, [CodePosition(14, 13)], func, project_root_path, "pytest", mode=TestingMode.BEHAVIOR
            )
            assert success
            success, new_test_perf = inject_profiling_into_existing_test(
                test_path, [CodePosition(14, 13)], func, project_root_path, "pytest", mode=TestingMode.PERFORMANCE
            )
    
            os.chdir(original_cwd)
            assert success
            assert new_test is not None
            assert new_test.replace('"', "'") == expected.format(
                module_path="code_to_optimize.tests.pytest.test_perfinjector_bubble_sort_parametrized_results_temp",
                tmp_dir_path=get_run_tmp_file(Path("test_return_values")),
            ).replace('"', "'")
            assert new_test_perf.replace('"', "'") == expected_perfonly.format(
                module_path="code_to_optimize.tests.pytest.test_perfinjector_bubble_sort_parametrized_results_temp",
                tmp_dir_path=get_run_tmp_file(Path("test_return_values")),
            ).replace('"', "'")
            #
            # Overwrite old test with new instrumented test
    
            with test_path.open("w") as f:
                f.write(new_test)
            with test_path_perf.open("w") as f:
                f.write(new_test_perf)
            test_env = os.environ.copy()
            test_env["CODEFLASH_TEST_ITERATION"] = "0"
            test_type = TestType.EXISTING_UNIT_TEST
            test_files = TestFiles(
                test_files=[
                    TestFile(
                        instrumented_behavior_file_path=test_path,
                        test_type=test_type,
                        original_file_path=test_path,
                        benchmarking_file_path=test_path_perf,
                    )
                ]
            )
            test_config = TestConfig(
                tests_root=tests_root,
                tests_project_rootdir=project_root_path,
                project_root_path=project_root_path,
                test_framework="pytest",
                pytest_cmd="pytest",
            )
            func_optimizer = FunctionOptimizer(function_to_optimize=func, test_cfg=test_config)
            test_results, coverage_data = func_optimizer.run_and_parse_tests(
                testing_type=TestingMode.BEHAVIOR,
                test_env=test_env,
                test_files=test_files,
                optimization_iteration=0,
                pytest_min_loops=1,
                pytest_max_loops=1,
                testing_time=0.1,
            )
            assert test_results[0].id.function_getting_tested == "sorter"
            assert test_results[0].id.iteration_id == "0_0"
            assert test_results[0].id.test_class_name is None
            assert test_results[0].id.test_function_name == "test_sort_parametrized"
            assert (
                test_results[0].id.test_module_path
                == "code_to_optimize.tests.pytest.test_perfinjector_bubble_sort_parametrized_results_temp"
            )
            assert test_results[0].runtime > 0
            assert test_results[0].did_pass
    
            assert test_results[1].id.function_getting_tested == "sorter"
            assert test_results[1].id.iteration_id == "0_1"
            assert test_results[1].id.test_class_name is None
            assert test_results[1].id.test_function_name == "test_sort_parametrized"
            assert (
                test_results[1].id.test_module_path
                == "code_to_optimize.tests.pytest.test_perfinjector_bubble_sort_parametrized_results_temp"
            )
            assert test_results[1].runtime > 0
            assert test_results[1].did_pass
    
            assert test_results[2].id.function_getting_tested == "sorter"
            assert test_results[2].id.iteration_id == "0_2"
            assert test_results[2].id.test_class_name is None
            assert test_results[2].id.test_function_name == "test_sort_parametrized"
            assert (
                test_results[2].id.test_module_path
                == "code_to_optimize.tests.pytest.test_perfinjector_bubble_sort_parametrized_results_temp"
            )
            assert test_results[2].runtime > 0
            assert test_results[2].did_pass
    
            test_results_perf, coverage_data = func_optimizer.run_and_parse_tests(
                testing_type=TestingMode.PERFORMANCE,
                test_env=test_env,
                test_files=test_files,
                optimization_iteration=0,
                pytest_min_loops=1,
                pytest_max_loops=1,
                testing_time=0.1,
            )
            assert test_results_perf[0].id.function_getting_tested == "sorter"
            assert test_results_perf[0].id.iteration_id == "0_0"
            assert test_results_perf[0].id.test_class_name is None
            assert test_results_perf[0].id.test_function_name == "test_sort_parametrized"
            assert (
                test_results_perf[0].id.test_module_path
                == "code_to_optimize.tests.pytest.test_perfinjector_bubble_sort_parametrized_results_temp"
            )
            assert test_results_perf[0].runtime > 0
            assert test_results_perf[0].did_pass
            assert test_results_perf[0].return_value is None
    
            assert test_results_perf[1].id.function_getting_tested == "sorter"
            assert test_results_perf[1].id.iteration_id == "0_1"
            assert test_results_perf[1].id.test_class_name is None
            assert test_results_perf[1].id.test_function_name == "test_sort_parametrized"
            assert (
                test_results_perf[1].id.test_module_path
                == "code_to_optimize.tests.pytest.test_perfinjector_bubble_sort_parametrized_results_temp"
            )
            assert test_results_perf[1].runtime > 0
            assert test_results_perf[1].did_pass
    
            out_str = """codeflash stdout: Sorting list
    result: [0.0, 1.0, 2.0, 3.0, 4.0, 5.0]"""
            assert out_str == test_results_perf[1].stdout
    
            assert test_results_perf[2].id.function_getting_tested == "sorter"
            assert test_results_perf[2].id.iteration_id == "0_2"
            assert test_results_perf[2].id.test_class_name is None
            assert test_results_perf[2].id.test_function_name == "test_sort_parametrized"
            assert (
                test_results_perf[2].id.test_module_path
                == "code_to_optimize.tests.pytest.test_perfinjector_bubble_sort_parametrized_results_temp"
            )
            assert test_results_perf[2].runtime > 0
            assert test_results_perf[2].did_pass
            ctx_result = func_optimizer.get_code_optimization_context()
            code_context: CodeOptimizationContext = ctx_result.unwrap()
            original_helper_code: dict[Path, str] = {}
            helper_function_paths = {hf.file_path for hf in code_context.helper_functions}
            for helper_function_path in helper_function_paths:
                with helper_function_path.open(encoding="utf8") as f:
                    helper_code = f.read()
                    original_helper_code[helper_function_path] = helper_code
            computed_fn_opt = True
            line_profiler_output_file = add_decorator_imports(
                func_optimizer.function_to_optimize, code_context)
            line_profile_results, _ = func_optimizer.run_and_parse_tests(
                testing_type=TestingMode.LINE_PROFILE,
                test_env=test_env,
                test_files=test_files,
                optimization_iteration=0,
                pytest_min_loops=1,
                pytest_max_loops=1,
                testing_time=0.1,
                line_profiler_output_file = line_profiler_output_file
            )
            tmp_lpr = list(line_profile_results["timings"].keys())
            assert len(tmp_lpr) == 1 and line_profile_results["timings"][tmp_lpr[0]][0][1]==3
        finally:
            if computed_fn_opt:
                func_optimizer.write_code_and_helpers(
                    func_optimizer.function_to_optimize_source_code, original_helper_code, func_optimizer.function_to_optimize.file_path
                )
            test_path.unlink(missing_ok=True)
            test_path_perf.unlink(missing_ok=True)
    
    
    def test_perfinjector_bubble_sort_parametrized_loop_results() -> None:
        computed_fn_opt = False
        code = """from code_to_optimize.bubble_sort import sorter
    import pytest
    
    
    @pytest.mark.parametrize(
        "input, expected_output",
        [
            ([5, 4, 3, 2, 1, 0], [0, 1, 2, 3, 4, 5]),
            ([5.0, 4.0, 3.0, 2.0, 1.0, 0.0], [0.0, 1.0, 2.0, 3.0, 4.0, 5.0]),
            (list(reversed(range(50))), list(range(50))),
        ],
    )
    def test_sort_parametrized_loop(input, expected_output):
        for i in range(2):
            output = sorter(input)
            assert output == expected_output
    """
        expected = (
            """import gc
    import os
    import sqlite3
    import time
    
    import dill as pickle
    import pytest
    
    from code_to_optimize.bubble_sort import sorter
    
    
    """
            + codeflash_wrap_string
            + """
    @pytest.mark.parametrize('input, expected_output', [([5, 4, 3, 2, 1, 0], [0, 1, 2, 3, 4, 5]), ([5.0, 4.0, 3.0, 2.0, 1.0, 0.0], [0.0, 1.0, 2.0, 3.0, 4.0, 5.0]), (list(reversed(range(50))), list(range(50)))])
    def test_sort_parametrized_loop(input, expected_output):
        codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
        codeflash_iteration = os.environ['CODEFLASH_TEST_ITERATION']
        codeflash_con = sqlite3.connect(f'{tmp_dir_path}_{{codeflash_iteration}}.sqlite')
        codeflash_cur = codeflash_con.cursor()
        codeflash_cur.execute('CREATE TABLE IF NOT EXISTS test_results (test_module_path TEXT, test_class_name TEXT, test_function_name TEXT, function_getting_tested TEXT, loop_index INTEGER, iteration_id TEXT, runtime INTEGER, return_value BLOB, verification_type TEXT)')
        for i in range(2):
            output = codeflash_wrap(sorter, '{module_path}', None, 'test_sort_parametrized_loop', 'sorter', '0_0', codeflash_loop_index, codeflash_cur, codeflash_con, input)
            assert output == expected_output
        codeflash_con.close()
    """
        )
        expected_perf = (
            """import gc
    import os
    import time
    
    import pytest
    
    from code_to_optimize.bubble_sort import sorter
    
    
    """
            + codeflash_wrap_perfonly_string
            + """
    @pytest.mark.parametrize('input, expected_output', [([5, 4, 3, 2, 1, 0], [0, 1, 2, 3, 4, 5]), ([5.0, 4.0, 3.0, 2.0, 1.0, 0.0], [0.0, 1.0, 2.0, 3.0, 4.0, 5.0]), (list(reversed(range(50))), list(range(50)))])
    def test_sort_parametrized_loop(input, expected_output):
        codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
        for i in range(2):
            output = codeflash_wrap(sorter, '{module_path}', None, 'test_sort_parametrized_loop', 'sorter', '0_0', codeflash_loop_index, input)
            assert output == expected_output
    """
        )
        code_path = (Path(__file__).parent.resolve() / "../code_to_optimize/bubble_sort.py").resolve()
        test_path = (
            Path(__file__).parent.resolve()
            / "../code_to_optimize/tests/pytest/test_perfinjector_bubble_sort_parametrized_loop_results_temp.py"
        ).resolve()
        test_path_behavior = (
            Path(__file__).parent.resolve()
            / "../code_to_optimize/tests/pytest/test_perfinjector_bubble_sort_parametrized_loop_results_temp.py"
        ).resolve()
        test_path_perf = (
            Path(__file__).parent.resolve()
            / "../code_to_optimize/tests/pytest/test_perfinjector_bubble_sort_parametrized_loop_results_temp_perf.py"
        ).resolve()
        try:
            with open(test_path, "w") as f:
                f.write(code)
    
            tests_root = (Path(__file__).parent.resolve() / "../code_to_optimize/tests/pytest/").resolve()
            project_root_path = (Path(__file__).parent.resolve() / "../").resolve()
            original_cwd = Path.cwd()
            run_cwd = Path(__file__).parent.parent.resolve()
    
            func = FunctionToOptimize(function_name="sorter", parents=[], file_path=code_path)
            os.chdir(run_cwd)
            success, new_test = inject_profiling_into_existing_test(
                test_path, [CodePosition(15, 17)], func, project_root_path, "pytest", mode=TestingMode.BEHAVIOR
            )
            assert success
            success, new_test_perf = inject_profiling_into_existing_test(
                test_path, [CodePosition(15, 17)], func, project_root_path, "pytest", mode=TestingMode.PERFORMANCE
            )
    
            os.chdir(original_cwd)
            assert success
            assert new_test is not None
            assert new_test.replace('"', "'") == expected.format(
                module_path="code_to_optimize.tests.pytest.test_perfinjector_bubble_sort_parametrized_loop_results_temp",
                tmp_dir_path=get_run_tmp_file(Path("test_return_values")),
            ).replace('"', "'")
    
            # Overwrite old test with new instrumented test
            with test_path_behavior.open("w") as f:
                f.write(new_test)
    
            assert new_test_perf.replace('"', "'") == expected_perf.format(
                module_path="code_to_optimize.tests.pytest.test_perfinjector_bubble_sort_parametrized_loop_results_temp",
                tmp_dir_path=get_run_tmp_file(Path("test_return_values")),
            ).replace('"', "'")
    
            # Overwrite old test with new instrumented test
            with test_path_perf.open("w") as f:
                f.write(new_test_perf)
    
            test_env = os.environ.copy()
            test_env["CODEFLASH_TEST_ITERATION"] = "0"
            test_type = TestType.EXISTING_UNIT_TEST
            test_files = TestFiles(
                test_files=[
                    TestFile(
                        instrumented_behavior_file_path=test_path_behavior,
                        test_type=test_type,
                        original_file_path=test_path,
                        benchmarking_file_path=test_path_perf,
                        tests_in_file=[
                            TestsInFile(
                                test_file=test_path,
                                test_class=None,
                                test_function="test_sort_parametrized_loop",
                                test_type=TestType.EXISTING_UNIT_TEST,
                            )
                        ],
                    )
                ]
            )
    
            test_config = TestConfig(
                tests_root=tests_root,
                tests_project_rootdir=project_root_path,
                project_root_path=project_root_path,
                test_framework="pytest",
                pytest_cmd="pytest",
            )
            func_optimizer = FunctionOptimizer(function_to_optimize=func, test_cfg=test_config)
            test_results, coverage_data = func_optimizer.run_and_parse_tests(
                testing_type=TestingMode.BEHAVIOR,
                test_env=test_env,
                test_files=test_files,
                optimization_iteration=0,
                pytest_min_loops=1,
                pytest_max_loops=1,
                testing_time=0.1,
            )
            assert test_results[0].id.function_getting_tested == "sorter"
            assert test_results[0].id.iteration_id == "0_0_0"
            assert test_results[0].id.test_class_name is None
            assert test_results[0].id.test_function_name == "test_sort_parametrized_loop"
            assert (
                test_results[0].id.test_module_path
                == "code_to_optimize.tests.pytest.test_perfinjector_bubble_sort_parametrized_loop_results_temp"
            )
            assert test_results[0].runtime > 0
            assert test_results[0].did_pass
            assert test_results[0].return_value == ([0, 1, 2, 3, 4, 5],)
    
            assert test_results[1].id.function_getting_tested == "sorter"
            assert test_results[1].id.iteration_id == "0_0_1"
            assert test_results[1].id.test_class_name is None
            assert test_results[1].id.test_function_name == "test_sort_parametrized_loop"
            assert (
                test_results[1].id.test_module_path
                == "code_to_optimize.tests.pytest.test_perfinjector_bubble_sort_parametrized_loop_results_temp"
            )
            assert test_results[1].runtime > 0
            assert test_results[1].did_pass
    
            assert test_results[2].id.function_getting_tested == "sorter"
            assert test_results[2].id.iteration_id == "0_0_2"
            assert test_results[2].id.test_class_name is None
            assert test_results[2].id.test_function_name == "test_sort_parametrized_loop"
            assert (
                test_results[2].id.test_module_path
                == "code_to_optimize.tests.pytest.test_perfinjector_bubble_sort_parametrized_loop_results_temp"
            )
            assert test_results[2].runtime > 0
            assert test_results[2].did_pass
    
            assert test_results[3].id.function_getting_tested == "sorter"
            assert test_results[3].id.iteration_id == "0_0_3"
            assert test_results[3].id.test_class_name is None
            assert test_results[3].id.test_function_name == "test_sort_parametrized_loop"
            assert (
                test_results[3].id.test_module_path
                == "code_to_optimize.tests.pytest.test_perfinjector_bubble_sort_parametrized_loop_results_temp"
            )
            assert test_results[3].runtime > 0
            assert test_results[3].did_pass
    
            assert test_results[4].id.function_getting_tested == "sorter"
            assert test_results[4].id.iteration_id == "0_0_4"
            assert test_results[4].id.test_class_name is None
            assert test_results[4].id.test_function_name == "test_sort_parametrized_loop"
            assert (
                test_results[4].id.test_module_path
                == "code_to_optimize.tests.pytest.test_perfinjector_bubble_sort_parametrized_loop_results_temp"
            )
            assert test_results[4].runtime > 0
            assert test_results[4].did_pass
    
            assert test_results[5].id.function_getting_tested == "sorter"
            assert test_results[5].id.iteration_id == "0_0_5"
            assert test_results[5].id.test_class_name is None
            assert test_results[5].id.test_function_name == "test_sort_parametrized_loop"
            assert (
                test_results[5].id.test_module_path
                == "code_to_optimize.tests.pytest.test_perfinjector_bubble_sort_parametrized_loop_results_temp"
            )
            assert test_results[5].runtime > 0
            assert test_results[5].did_pass
    
            test_results, _ = func_optimizer.run_and_parse_tests(
                testing_type=TestingMode.PERFORMANCE,
                test_env=test_env,
                test_files=test_files,
                optimization_iteration=0,
                pytest_min_loops=1,
                pytest_max_loops=1,
                testing_time=0.1,
            )
    
            assert test_results[0].id.function_getting_tested == "sorter"
            assert test_results[0].id.iteration_id == "0_0_0"
            assert test_results[0].id.test_class_name is None
            assert test_results[0].id.test_function_name == "test_sort_parametrized_loop"
            assert (
                test_results[0].id.test_module_path
                == "code_to_optimize.tests.pytest.test_perfinjector_bubble_sort_parametrized_loop_results_temp"
            )
            assert test_results[0].runtime > 0
            assert test_results[0].did_pass
            assert test_results[0].return_value is None
    
            assert test_results[1].id.function_getting_tested == "sorter"
            assert test_results[1].id.iteration_id == "0_0_1"
            assert test_results[1].id.test_class_name is None
            assert test_results[1].id.test_function_name == "test_sort_parametrized_loop"
            assert (
                test_results[1].id.test_module_path
                == "code_to_optimize.tests.pytest.test_perfinjector_bubble_sort_parametrized_loop_results_temp"
            )
            assert test_results[1].runtime > 0
            assert test_results[1].did_pass
            assert test_results[1].return_value is None
    
            assert test_results[2].id.function_getting_tested == "sorter"
            assert test_results[2].id.iteration_id == "0_0_2"
            assert test_results[2].id.test_class_name is None
            assert test_results[2].id.test_function_name == "test_sort_parametrized_loop"
            assert (
                test_results[2].id.test_module_path
                == "code_to_optimize.tests.pytest.test_perfinjector_bubble_sort_parametrized_loop_results_temp"
            )
            assert test_results[2].runtime > 0
            assert test_results[2].did_pass
            assert test_results[2].return_value is None
    
            assert test_results[3].id.function_getting_tested == "sorter"
            assert test_results[3].id.iteration_id == "0_0_3"
            assert test_results[3].id.test_class_name is None
            assert test_results[3].id.test_function_name == "test_sort_parametrized_loop"
            assert (
                test_results[3].id.test_module_path
                == "code_to_optimize.tests.pytest.test_perfinjector_bubble_sort_parametrized_loop_results_temp"
            )
            assert test_results[3].runtime > 0
            assert test_results[3].did_pass
            assert test_results[3].return_value is None
    
            assert test_results[4].id.function_getting_tested == "sorter"
            assert test_results[4].id.iteration_id == "0_0_4"
            assert test_results[4].id.test_class_name is None
            assert test_results[4].id.test_function_name == "test_sort_parametrized_loop"
            assert (
                test_results[4].id.test_module_path
                == "code_to_optimize.tests.pytest.test_perfinjector_bubble_sort_parametrized_loop_results_temp"
            )
            assert test_results[4].runtime > 0
            assert test_results[4].did_pass
            assert test_results[4].return_value is None
    
            assert test_results[5].id.function_getting_tested == "sorter"
            assert test_results[5].id.iteration_id == "0_0_5"
            assert test_results[5].id.test_class_name is None
            assert test_results[5].id.test_function_name == "test_sort_parametrized_loop"
            assert (
                test_results[5].id.test_module_path
                == "code_to_optimize.tests.pytest.test_perfinjector_bubble_sort_parametrized_loop_results_temp"
            )
            assert test_results[5].runtime > 0
            assert test_results[5].did_pass
            ctx_result = func_optimizer.get_code_optimization_context()
            code_context: CodeOptimizationContext = ctx_result.unwrap()
            original_helper_code: dict[Path, str] = {}
            helper_function_paths = {hf.file_path for hf in code_context.helper_functions}
            for helper_function_path in helper_function_paths:
                with helper_function_path.open(encoding="utf8") as f:
                    helper_code = f.read()
                    original_helper_code[helper_function_path] = helper_code
            computed_fn_opt = True
            line_profiler_output_file = add_decorator_imports(
                func_optimizer.function_to_optimize, code_context)
            line_profile_results, _ = func_optimizer.run_and_parse_tests(
                testing_type=TestingMode.LINE_PROFILE,
                test_env=test_env,
                test_files=test_files,
                optimization_iteration=0,
                pytest_min_loops=1,
                pytest_max_loops=1,
                testing_time=0.1,
                line_profiler_output_file = line_profiler_output_file
            )
            tmp_lpr = list(line_profile_results["timings"].keys())
            assert len(tmp_lpr) == 1 and line_profile_results["timings"][tmp_lpr[0]][0][1]==6
        finally:
            if computed_fn_opt:
                func_optimizer.write_code_and_helpers(
                    func_optimizer.function_to_optimize_source_code, original_helper_code, func_optimizer.function_to_optimize.file_path
                )
            test_path.unlink(missing_ok=True)
            test_path_behavior.unlink(missing_ok=True)
            test_path_perf.unlink(missing_ok=True)
    
    
    def test_perfinjector_bubble_sort_loop_results() -> None:
        computed_fn_opt = False
        code = """from code_to_optimize.bubble_sort import sorter
    
    
    def test_sort():
        inputs = [[5, 4, 3, 2, 1, 0], [5.0, 4.0, 3.0, 2.0, 1.0, 0.0], list(reversed(range(50)))]
        expected_outputs = [[0, 1, 2, 3, 4, 5], [0.0, 1.0, 2.0, 3.0, 4.0, 5.0], list(range(50))]
    
        for i in range(3):
            input = inputs[i]
            expected_output = expected_outputs[i]
            output = sorter(input)
            assert output == expected_output"""
    
        expected = (
            """import gc
    import os
    import sqlite3
    import time
    
    import dill as pickle
    
    from code_to_optimize.bubble_sort import sorter
    
    
    """
            + codeflash_wrap_string
            + """
    def test_sort():
        codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
        codeflash_iteration = os.environ['CODEFLASH_TEST_ITERATION']
        codeflash_con = sqlite3.connect(f'{tmp_dir_path}_{{codeflash_iteration}}.sqlite')
        codeflash_cur = codeflash_con.cursor()
        codeflash_cur.execute('CREATE TABLE IF NOT EXISTS test_results (test_module_path TEXT, test_class_name TEXT, test_function_name TEXT, function_getting_tested TEXT, loop_index INTEGER, iteration_id TEXT, runtime INTEGER, return_value BLOB, verification_type TEXT)')
        inputs = [[5, 4, 3, 2, 1, 0], [5.0, 4.0, 3.0, 2.0, 1.0, 0.0], list(reversed(range(50)))]
        expected_outputs = [[0, 1, 2, 3, 4, 5], [0.0, 1.0, 2.0, 3.0, 4.0, 5.0], list(range(50))]
        for i in range(3):
            input = inputs[i]
            expected_output = expected_outputs[i]
            output = codeflash_wrap(sorter, '{module_path}', None, 'test_sort', 'sorter', '2_2', codeflash_loop_index, codeflash_cur, codeflash_con, input)
            assert output == expected_output
        codeflash_con.close()
    """
        )
    
        expected_perf = (
            """import gc
    import os
    import time
    
    from code_to_optimize.bubble_sort import sorter
    
    
    """
            + codeflash_wrap_perfonly_string
            + """
    def test_sort():
        codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
        inputs = [[5, 4, 3, 2, 1, 0], [5.0, 4.0, 3.0, 2.0, 1.0, 0.0], list(reversed(range(50)))]
        expected_outputs = [[0, 1, 2, 3, 4, 5], [0.0, 1.0, 2.0, 3.0, 4.0, 5.0], list(range(50))]
        for i in range(3):
            input = inputs[i]
            expected_output = expected_outputs[i]
            output = codeflash_wrap(sorter, '{module_path}', None, 'test_sort', 'sorter', '2_2', codeflash_loop_index, input)
            assert output == expected_output
    """
        )
        code_path = (Path(__file__).parent.resolve() / "../code_to_optimize/bubble_sort.py").resolve()
        test_path = (
            Path(__file__).parent.resolve()
            / "../code_to_optimize/tests/pytest/test_perfinjector_bubble_sort_loop_results_temp.py"
        ).resolve()
        test_path_behavior = (
            Path(__file__).parent.resolve()
            / "../code_to_optimize/tests/pytest/test_perfinjector_bubble_sort_loop_results_temp_behavior.py"
        ).resolve()
        test_path_perf = (
            Path(__file__).parent.resolve()
            / "../code_to_optimize/tests/pytest/test_perfinjector_bubble_sort_loop_results_temp_perf.py"
        ).resolve()
        try:
            with test_path.open("w") as f:
                f.write(code)
    
            tests_root = (Path(__file__).parent.resolve() / "../code_to_optimize/tests/pytest/").resolve()
            project_root_path = (Path(__file__).parent.resolve() / "../").resolve()
            run_cwd = Path(__file__).parent.parent.resolve()
            original_cwd = Path.cwd()
    
            func = FunctionToOptimize(function_name="sorter", parents=[], file_path=code_path)
            os.chdir(str(run_cwd))
            success, new_test_behavior = inject_profiling_into_existing_test(
                test_path, [CodePosition(11, 17)], func, project_root_path, "pytest", mode=TestingMode.BEHAVIOR
            )
            assert success
            success, new_test_perf = inject_profiling_into_existing_test(
                test_path, [CodePosition(11, 17)], func, project_root_path, "pytest", mode=TestingMode.PERFORMANCE
            )
            os.chdir(original_cwd)
            assert success
            assert new_test_behavior is not None
            assert new_test_behavior.replace('"', "'") == expected.format(
                module_path="code_to_optimize.tests.pytest.test_perfinjector_bubble_sort_loop_results_temp",
                tmp_dir_path=get_run_tmp_file(Path("test_return_values")),
            ).replace('"', "'")
    
            assert new_test_perf.replace('"', "'") == expected_perf.format(
                module_path="code_to_optimize.tests.pytest.test_perfinjector_bubble_sort_loop_results_temp",
                tmp_dir_path=get_run_tmp_file(Path("test_return_values")),
            ).replace('"', "'")
    
            # Overwrite old test with new instrumented test
    
            with test_path_behavior.open("w") as f:
                f.write(new_test_behavior)
            with test_path_perf.open("w") as f:
                f.write(new_test_perf)
            test_env = os.environ.copy()
            test_env["CODEFLASH_TEST_ITERATION"] = "0"
            test_type = TestType.EXISTING_UNIT_TEST
            test_files = TestFiles(
                test_files=[
                    TestFile(
                        instrumented_behavior_file_path=test_path_behavior,
                        test_type=test_type,
                        original_file_path=test_path,
                        benchmarking_file_path=test_path_perf,
                        tests_in_file=[
                            TestsInFile(
                                test_file=test_path,
                                test_class=None,
                                test_function="test_sort",
                                test_type=TestType.EXISTING_UNIT_TEST,
                            )
                        ],
                    )
                ]
            )
    
            test_config = TestConfig(
                tests_root=tests_root,
                tests_project_rootdir=project_root_path,
                project_root_path=project_root_path,
                test_framework="pytest",
                pytest_cmd="pytest",
            )
            func_optimizer = FunctionOptimizer(function_to_optimize=func, test_cfg=test_config)
            test_results, coverage_data = func_optimizer.run_and_parse_tests(
                testing_type=TestingMode.BEHAVIOR,
                test_env=test_env,
                test_files=test_files,
                optimization_iteration=0,
                pytest_min_loops=1,
                pytest_max_loops=1,
                testing_time=0.1,
            )
            assert test_results[0].id.function_getting_tested == "sorter"
            assert test_results[0].id.iteration_id == "2_2_0"
            assert test_results[0].id.test_class_name is None
            assert test_results[0].id.test_function_name == "test_sort"
            assert (
                test_results[0].id.test_module_path
                == "code_to_optimize.tests.pytest.test_perfinjector_bubble_sort_loop_results_temp"
            )
            assert test_results[0].runtime > 0
            assert test_results[0].did_pass
            assert test_results[0].return_value == ([0, 1, 2, 3, 4, 5],)
    
            assert test_results[1].id.function_getting_tested == "sorter"
            assert test_results[1].id.iteration_id == "2_2_1"
            assert test_results[1].id.test_class_name is None
            assert test_results[1].id.test_function_name == "test_sort"
            assert (
                test_results[1].id.test_module_path
                == "code_to_optimize.tests.pytest.test_perfinjector_bubble_sort_loop_results_temp"
            )
            assert test_results[1].runtime > 0
            assert test_results[1].did_pass
    
            assert test_results[2].id.function_getting_tested == "sorter"
            assert test_results[2].id.iteration_id == "2_2_2"
            assert test_results[2].id.test_class_name is None
            assert test_results[2].id.test_function_name == "test_sort"
            assert (
                test_results[2].id.test_module_path
                == "code_to_optimize.tests.pytest.test_perfinjector_bubble_sort_loop_results_temp"
            )
            assert test_results[2].runtime > 0
            assert test_results[2].did_pass
            test_results, coverage_data = func_optimizer.run_and_parse_tests(
                testing_type=TestingMode.PERFORMANCE,
                test_env=test_env,
                test_files=test_files,
                optimization_iteration=0,
                pytest_min_loops=1,
                pytest_max_loops=1,
                testing_time=0.1,
            )
            assert test_results[0].id.function_getting_tested == "sorter"
            assert test_results[0].id.iteration_id == "2_2_0"
            assert test_results[0].id.test_class_name is None
            assert test_results[0].id.test_function_name == "test_sort"
            assert (
                test_results[0].id.test_module_path
                == "code_to_optimize.tests.pytest.test_perfinjector_bubble_sort_loop_results_temp"
            )
            assert test_results[0].runtime > 0
            assert test_results[0].did_pass
            assert test_results[0].return_value is None
            out_str = """codeflash stdout: Sorting list
    result: [0, 1, 2, 3, 4, 5]
    
    codeflash stdout: Sorting list
    result: [0.0, 1.0, 2.0, 3.0, 4.0, 5.0]
    
    codeflash stdout: Sorting list
    result: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49]"""
            assert test_results[1].stdout == out_str
            assert test_results[1].id.function_getting_tested == "sorter"
            assert test_results[1].id.iteration_id == "2_2_1"
            assert test_results[1].id.test_class_name is None
            assert test_results[1].id.test_function_name == "test_sort"
            assert (
                test_results[1].id.test_module_path
                == "code_to_optimize.tests.pytest.test_perfinjector_bubble_sort_loop_results_temp"
            )
            assert test_results[1].runtime > 0
            assert test_results[1].did_pass
    
            assert test_results[2].id.function_getting_tested == "sorter"
            assert test_results[2].id.iteration_id == "2_2_2"
            assert test_results[2].id.test_class_name is None
            assert test_results[2].id.test_function_name == "test_sort"
            assert (
                test_results[2].id.test_module_path
                == "code_to_optimize.tests.pytest.test_perfinjector_bubble_sort_loop_results_temp"
            )
            assert test_results[2].runtime > 0
            assert test_results[2].did_pass
            ctx_result = func_optimizer.get_code_optimization_context()
            code_context: CodeOptimizationContext = ctx_result.unwrap()
            original_helper_code: dict[Path, str] = {}
            helper_function_paths = {hf.file_path for hf in code_context.helper_functions}
            for helper_function_path in helper_function_paths:
                with helper_function_path.open(encoding="utf8") as f:
                    helper_code = f.read()
                    original_helper_code[helper_function_path] = helper_code
            computed_fn_opt = True
            line_profiler_output_file = add_decorator_imports(
                func_optimizer.function_to_optimize, code_context)
            line_profile_results, _ = func_optimizer.run_and_parse_tests(
                testing_type=TestingMode.LINE_PROFILE,
                test_env=test_env,
                test_files=test_files,
                optimization_iteration=0,
                pytest_min_loops=1,
                pytest_max_loops=1,
                testing_time=0.1,
                line_profiler_output_file = line_profiler_output_file
            )
            tmp_lpr = list(line_profile_results["timings"].keys())
            assert len(tmp_lpr) == 1 and line_profile_results["timings"][tmp_lpr[0]][0][1]==3
        finally:
            if computed_fn_opt is True:
                func_optimizer.write_code_and_helpers(
                    func_optimizer.function_to_optimize_source_code, original_helper_code, func_optimizer.function_to_optimize.file_path
                )
            test_path.unlink(missing_ok=True)
            test_path_perf.unlink(missing_ok=True)
            test_path_behavior.unlink(missing_ok=True)
    
    
    def test_perfinjector_bubble_sort_unittest_results() -> None:
        code = """import unittest
    
    from code_to_optimize.bubble_sort import sorter
    
    
    class TestPigLatin(unittest.TestCase):
        def test_sort(self):
            input = [5, 4, 3, 2, 1, 0]
            output = sorter(input)
            self.assertEqual(output, [0, 1, 2, 3, 4, 5])
    
            input = [5.0, 4.0, 3.0, 2.0, 1.0, 0.0]
            output = sorter(input)
            self.assertEqual(output, [0.0, 1.0, 2.0, 3.0, 4.0, 5.0])
    
            input = list(reversed(range(50)))
            output = sorter(input)
            self.assertEqual(output, list(range(50)))
    """
    
        expected = (
            """import gc
    import os
    import sqlite3
    import time
    import unittest
    
    import dill as pickle
    import timeout_decorator
    
    from code_to_optimize.bubble_sort import sorter
    
    
    """
            + codeflash_wrap_string
            + """
    class TestPigLatin(unittest.TestCase):
    
        @timeout_decorator.timeout(15)
        def test_sort(self):
            codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
            codeflash_iteration = os.environ['CODEFLASH_TEST_ITERATION']
            codeflash_con = sqlite3.connect(f'{tmp_dir_path}_{{codeflash_iteration}}.sqlite')
            codeflash_cur = codeflash_con.cursor()
            codeflash_cur.execute('CREATE TABLE IF NOT EXISTS test_results (test_module_path TEXT, test_class_name TEXT, test_function_name TEXT, function_getting_tested TEXT, loop_index INTEGER, iteration_id TEXT, runtime INTEGER, return_value BLOB, verification_type TEXT)')
            input = [5, 4, 3, 2, 1, 0]
            output = codeflash_wrap(sorter, '{module_path}', 'TestPigLatin', 'test_sort', 'sorter', '1', codeflash_loop_index, codeflash_cur, codeflash_con, input)
            self.assertEqual(output, [0, 1, 2, 3, 4, 5])
            input = [5.0, 4.0, 3.0, 2.0, 1.0, 0.0]
            output = codeflash_wrap(sorter, '{module_path}', 'TestPigLatin', 'test_sort', 'sorter', '4', codeflash_loop_index, codeflash_cur, codeflash_con, input)
            self.assertEqual(output, [0.0, 1.0, 2.0, 3.0, 4.0, 5.0])
            input = list(reversed(range(50)))
            output = codeflash_wrap(sorter, '{module_path}', 'TestPigLatin', 'test_sort', 'sorter', '7', codeflash_loop_index, codeflash_cur, codeflash_con, input)
            self.assertEqual(output, list(range(50)))
            codeflash_con.close()
    """
        )
        expected_perf = (
            """import gc
    import os
    import time
    import unittest
    
    import timeout_decorator
    
    from code_to_optimize.bubble_sort import sorter
    
    
    """
            + codeflash_wrap_perfonly_string
            + """
    class TestPigLatin(unittest.TestCase):
    
        @timeout_decorator.timeout(15)
        def test_sort(self):
            codeflash_loop_index = int(os.environ['CODEFLASH_LOOP_INDEX'])
            input = [5, 4, 3, 2, 1, 0]
            output = codeflash_wrap(sorter, '{module_path}', 'TestPigLatin', 'test_sort', 'sorter', '1', codeflash_loop_index, input)
            self.assertEqual(output, [0, 1, 2, 3, 4, 5])
            input = [5.0, 4.0, 3.0, 2.0, 1.0, 0.0]
            output = codeflash_wrap(sorter, '{module_path}', 'TestPigLatin', 'test_sort', 'sorter', '4', codeflash_loop_index, input)
            self.assertEqual(output, [0.0, 1.0, 2.0, 3.0, 4.0, 5.0])
            input = list(reversed(range(50)))
            output = codeflash_wrap(sorter, '{module_path}', 'TestPigLatin', 'test_sort', 'sorter', '7', codeflash_loop_index, input)
            self.assertEqual(output, list(range(50)))
    """
        )
        code_path = (Path(__file__).parent.resolve() / "../code_to_optimize/bubble_sort.py").resolve()
        test_path = (
            Path(__file__).parent.resolve()
            / "../code_to_optimize/tests/unittest/test_perfinjector_bubble_sort_unittest_results_temp.py"
        ).resolve()
        test_path_behavior = (
            Path(__file__).parent.resolve()
            / "../code_to_optimize/tests/unittest/test_perfinjector_bubble_sort_unittest_results_temp_behavior.py"
        ).resolve()
        test_path_perf = (
            Path(__file__).parent.resolve()
            / "../code_to_optimize/tests/unittest/test_perfinjector_bubble_sort_unittest_results_temp_perf.py"
        ).resolve()
        try:
            with test_path.open("w") as f:
                f.write(code)
    
            tests_root = (Path(__file__).parent.resolve() / "../code_to_optimize/tests/unittest/").resolve()
            project_root_path = (Path(__file__).parent.resolve() / "../").resolve()
            run_cwd = Path(__file__).parent.parent.resolve()
            original_cwd = Path.cwd()
    
            func = FunctionToOptimize(function_name="sorter", parents=[], file_path=code_path)
            os.chdir(run_cwd)
            success, new_test_behavior = inject_profiling_into_existing_test(
                test_path,
                [CodePosition(9, 17), CodePosition(13, 17), CodePosition(17, 17)],
                func,
                project_root_path,
                "unittest",
                mode=TestingMode.BEHAVIOR,
            )
            assert success
            success, new_test_perf = inject_profiling_into_existing_test(
                test_path,
                [CodePosition(9, 17), CodePosition(13, 17), CodePosition(17, 17)],
                func,
                project_root_path,
                "unittest",
                mode=TestingMode.PERFORMANCE,
            )
            os.chdir(original_cwd)
    
            assert success
            assert new_test_behavior is not None
            assert new_test_behavior.replace('"', "'") == expected.format(
                module_path="code_to_optimize.tests.unittest.test_perfinjector_bubble_sort_unittest_results_temp",
                tmp_dir_path=get_run_tmp_file(Path("test_return_values")),
            ).replace('"', "'")
            assert new_test_perf.replace('"', "'") == expected_perf.format(
                module_path="code_to_optimize.tests.unittest.test_perfinjector_bubble_sort_unittest_results_temp",
                tmp_dir_path=get_run_tmp_file(Path("test_return_values")),
            ).replace('"', "'")
            #
            # Overwrite old test with new instrumented test
            with test_path_behavior.open("w") as f:
                f.write(new_test_behavior)
            with test_path_perf.open("w") as f:
                f.write(new_test_perf)
    
            test_env = os.environ.copy()
            test_env["CODEFLASH_TEST_ITERATION"] = "0"
            test_env["CODEFLASH_LOOP_INDEX"] = "1"
            test_type = TestType.EXISTING_UNIT_TEST
            test_files = TestFiles(
                test_files=[
                    TestFile(
                        instrumented_behavior_file_path=test_path_behavior,
                        test_type=test_type,
                        original_file_path=test_path,
                        benchmarking_file_path=test_path_perf,
                        tests_in_file=[
                            TestsInFile(
                                test_file=test_path,
                                test_class="TestPigLatin",
                                test_function="test_sort",
                                test_type=TestType.EXISTING_UNIT_TEST,
                            )
                        ],
                    )
                ]
            )
            test_config = TestConfig(
                tests_root=tests_root,
                tests_project_rootdir=project_root_path,
                project_root_path=project_root_path,
                test_framework="unittest",
                pytest_cmd="pytest",
            )
            func_optimizer = FunctionOptimizer(function_to_optimize=func, test_cfg=test_config)
            test_results, coverage_data = func_optimizer.run_and_parse_tests(
                testing_type=TestingMode.BEHAVIOR,
                test_env=test_env,
                test_files=test_files,
                optimization_iteration=0,
                pytest_min_loops=1,
                pytest_max_loops=1,
                testing_time=0.1,
            )
            assert test_results[0].id.function_getting_tested == "sorter"
            assert test_results[0].id.iteration_id == "1_0"
            assert test_results[0].id.test_class_name =...

    @github-actions
    Copy link

    PR Code Suggestions ✨

    Explore these optional code suggestions:

    CategorySuggestion                                                                                                                                    Impact
    Possible issue
    Unify string indentation

    Remove the extra indentation inside the triple-quoted string to match the other
    instances and prevent unexpected leading whitespace in the expected output.

    tests/test_instrument_tests.py [2839]

    -expected += """    print(f"!######{test_module_name}:{(test_class_name + '.' if test_class_name else '')}{test_name}:{function_name}:{loop_index}:{invocation_id}######!")"""
    +expected += """print(f"!######{test_module_name}:{(test_class_name + '.' if test_class_name else '')}{test_name}:{function_name}:{loop_index}:{invocation_id}######!")"""
    Suggestion importance[1-10]: 6

    __

    Why: The suggestion correctly addresses a minor formatting issue by removing unintended extra indentation in the string literal, ensuring consistent output compared to other instances, though its impact is relatively limited.

    Low

    @alvin-r alvin-r closed this Apr 19, 2025
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

    Labels

    Review effort 2/5 workflow-modified This PR modifies GitHub Actions workflows

    Projects

    None yet

    Development

    Successfully merging this pull request may close these issues.

    2 participants